package com.itheima.health.security;

import com.alibaba.fastjson.JSON;
import com.itheima.health.entity.Result;
import com.itheima.health.pojo.Permission;
import com.itheima.health.pojo.Role;
import com.itheima.health.pojo.User;
import org.springframework.util.AntPathMatcher;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

@WebFilter(urlPatterns = "/*")
public class HealthSecurityFilter implements Filter {
    private String[] Url = new String[]{
            "/user/login",
            "/user/logout",
            "/common/**",
            "/mobile/**",
    };
    private Map<String, String> loginAuthUrlMap = new HashMap<>();

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        initAuthUrlMap();
    }
    private void initAuthUrlMap() {
        loginAuthUrlMap.put("/checkitem/delete", "CHECKITEM_DELETE");
        loginAuthUrlMap.put("/checkitem/add", "CHECKITEM_ADD");
        loginAuthUrlMap.put("/checkitem/edit", "CHECKITEM_EDIT");
        loginAuthUrlMap.put("/checkitem/findPage", "CHECKITEM_QUERY");
        loginAuthUrlMap.put("/checkgroup/delete", "CHECKGROUP_DELETE");
        loginAuthUrlMap.put("/checkgroup/add", "CHECKGROUP_ADD");
        loginAuthUrlMap.put("/checkgroup/edit", "CHECKGROUP_EDIT");
        loginAuthUrlMap.put("/checkgroup/findPage", "CHECKGROUP_QUERY");
        loginAuthUrlMap.put("/setmeal/delete", "CHECKITEM_DELETE");
        loginAuthUrlMap.put("/setmeal/add", "SETMEAL_ADD");
        loginAuthUrlMap.put("/setmeal/edit", "SETMEAL_EDIT");
        loginAuthUrlMap.put("/setmeal/findPage", "SETMEAL_QUERY");
        loginAuthUrlMap.put("/menu/delete", "MENU_DELETE");
        loginAuthUrlMap.put("/menu/add", "MENU_ADD");
        loginAuthUrlMap.put("/menu/edit", "MENU_EDIT");
        loginAuthUrlMap.put("/menu/findPage", "MENU_QUERY");
        loginAuthUrlMap.put("/report/**", "REPORT_VIEW");
        loginAuthUrlMap.put("/ordersetting/**", "ORDERSETTING");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String uri = request.getRequestURI();
        boolean isNoLoginAccess = checkURI(uri);
        if (isNoLoginAccess) {

            filterChain.doFilter(request, response);
            return;
        }
        if (request.getSession().getAttribute("user") != null) {
            User user = (User) request.getSession().getAttribute("user");
            boolean isLoginAuth = checkLoginAuthURI(uri, user);
            if (isLoginAuth) {
                filterChain.doFilter(request, response);
            } else {
                response.setContentType("application/json; charset=UTF-8");
                response.getWriter().write(JSON.toJSONString(new Result(false, "无操作权限")));
            }
        } else if (request.getSession().getAttribute("member") != null) {
            filterChain.doFilter(request, response);
        } else {
            response.setContentType("application/json; charset=UTF-8");
            response.getWriter().write(JSON.toJSONString(new Result(false, "请重新登录")));
        }
    }

    private boolean checkURI(String reqUri) {
        AntPathMatcher pathMatcher = new AntPathMatcher();
        for (String url : Url) {
            if (pathMatcher.match(url, reqUri)) {
                return true;
            }
        }
        return false;
    }

    private boolean checkLoginAuthURI(String reqUri, User user) {
        AntPathMatcher pathMatcher = new AntPathMatcher();
        Set<String> keySets = loginAuthUrlMap.keySet();
        String currKeyUrl = null;
        for (String urLKey : keySets) {
            if (pathMatcher.match(urLKey, reqUri)) {
                currKeyUrl = urLKey;
            }
        }
        if (currKeyUrl == null) {
            return true;
        }
        String authKeyword = loginAuthUrlMap.get(currKeyUrl);
        Set<Role> roles = user.getRoles();
        for (Role role : roles) {
            Set<Permission> permissions = role.getPermissions();
            for (Permission p : permissions) {
                if (p.getKeyword().equals(authKeyword)) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public void destroy() {

    }

}